home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 355_02 / slk2.exe / SPP / SPP.C < prev    next >
C/C++ Source or Header  |  1991-06-09  |  20KB  |  1,016 lines

  1. /*
  2.     New Sherlock preprocessor -- Main routine
  3.  
  4.     PUBLIC DOMAIN SOFTWARE -- See below.
  5.  
  6.     source:  spp.c
  7.     started: October 7, 1985
  8.  
  9.     Version 1.0:  July 22, 1988
  10.     Version 1.0a: November 1, 1988 bug fix in sys.c
  11.     Version 1.0b: November 3, 1988 bug fix in spp.c, def.c
  12.     Version 1.1:
  13.         February 10, 1989 bug fix in spp.c and dir.c
  14.         February 16, 1989 is_sherlock() added.
  15.     Version 1.1A: February 25, 1989: bug fix in so_disable().
  16.     Version 1.2:  February 27, 1989: sl_sbout support().
  17.     Version 1.4:  June 22, June 26 and June 27, 1989:
  18.         
  19.         o Added support for INCLUDE environment variable in main().
  20.         o sysnext() changed to eliminate all backslash-newlines.
  21.         o tok.c, def.c changed to eliminate backslash-newline logic.
  22.           (eliminated with #ifdef BACKSLASH_NEWLINE)
  23.         o fixed comment bug in tok.c.
  24.         o fixed run-on macro expansion bug in def.c.
  25.  
  26.     Version 1.5: August 4, 1989
  27.         o -x option disables single-line comments.
  28.         o Added slc_flag as a sentinal to single-line comments.
  29.         o Enabled single-line comment.
  30.         o Added single() support for control-c interrupt.
  31.  
  32.     Version 1.7, 1991
  33.         o This was the first Public Domain version.
  34.         o Bug fix to is_reserved.
  35.         o Bug fix to st_init.
  36.         o Bug fixes in sem.c
  37.  
  38.  
  39.     PUBLIC DOMAIN SOFTWARE
  40.  
  41.     Sherlock, including the SPP, SDEL and SDIF programs, was placed in
  42.     the public domain on June 15, 1991, by its author,
  43.  
  44.         Edward K. Ream
  45.         166 North Prospect Ave.
  46.         Madison, WI 53705.
  47.         (608) 257-0802
  48.  
  49.     Sherlock may be used for any commercial or non-commercial purpose.
  50.  
  51.  
  52.     DISCLAIMER OF WARRANTIES
  53.  
  54.     Edward K. Ream (Ream) specifically disclaims all warranties,
  55.     expressed or implied, with respect to this computer software,
  56.     including but not limited to implied warranties of merchantability
  57.     and fitness for a particular purpose.  In no event shall Ream be
  58.     liable for any loss of profit or any commercial damage, including
  59.     but not limited to special, incidental consequential or other damages.
  60.     
  61. */
  62.  
  63. #include "spp.h"
  64.  
  65. /* Declare local routines. */
  66. static void    synonyms(void);
  67. static void    set_syn    (char *, char *);
  68.  
  69. #define SIGNON "SPP v1.7: June 15, 1991"
  70. #define DEBUG_WARNING "---debug version---"
  71.  
  72. #ifdef SHERLOCK
  73. #define USAGE1 "usage: spp in out [options] ++/--routine\n\n"
  74. #else
  75. #define USAGE1 "usage: spp in out [options]\n\n"
  76. #endif
  77.  
  78. #define USAGE2  "-d id=value  #define id value\n"
  79. #define USAGE3    "-f <file>    use synonym file\n"
  80. #define USAGE4  "-i           insert include \"sl.h\" at start of file\n"
  81. #define USAGE5  "-n           allow nested comments\n"
  82. #define USAGE6  "-o           use usr output routines instead of printf\n"
  83. #define USAGE7  "-s <path>    set search path for #include's\n"
  84. #define USAGE8    "-t           insert tick-style macros\n"
  85. #define USAGE9  "-u id        #undef id\n"
  86. #define USAGE10 "-x           do not allow single-line comments\n"
  87. #define USAGE11 "-?           print the version number and exit\n"
  88.  
  89. void
  90. main(int argc, char **argv)
  91. {
  92.     char *in = NULL, *out = NULL;
  93.     char *arg;
  94.     char *def;
  95.     char *p, *p1;
  96.     char path_buf[400];
  97.  
  98.     /* These two calls MUST come before any others. */
  99.     SL_INIT();
  100.     SL_PARSE(argc, argv, "++", "--");
  101.  
  102.     /*
  103.         The call to mst_init() MUST be placed here so we can define
  104.         macros using the -d option.
  105.  
  106.         The call to mst2_init() must FOLLOW the gathering of
  107.         command line arguments so that the __line__ and __file__
  108.         macros may be disabled using the -u option.
  109.     */
  110.     mst_init();
  111.     st_init();
  112.  
  113.     /* Allow user to abort. */
  114.     syscsts();
  115.  
  116.     TICK("main");
  117.  
  118.     /* Always put out the sign on message. */
  119. #ifdef SHERLOCK
  120.     printf("%s%s\n", SIGNON, DEBUG_WARNING);
  121. #else
  122.     printf("%s\n", SIGNON);
  123. #endif
  124.  
  125.  
  126.     /* Make first test for correct command line. */
  127.     if (argc == 2 && str_eq(argv[1], "-?")) {
  128.         exit(BAD_EXIT);
  129.     }
  130.     if (argc < 3) {
  131.         printf("%s%s%s%s", USAGE1,  USAGE2,  USAGE3,  USAGE4);
  132.         printf("%s%s%s%s", USAGE5,  USAGE6,  USAGE7,  USAGE8);
  133.         printf("%s%s%s", USAGE9, USAGE10, USAGE11);
  134.         exit(BAD_EXIT);
  135.     }
  136.  
  137.     /* Process all the arguments on the command line. */
  138.     argc--;
  139.     argv++;
  140.     while (argc-- > 0) {
  141.         arg = *argv++;
  142.  
  143.         if(str_eq(arg, "-d")) {
  144.             /* Define a variable. */
  145.             if (argc--) {
  146.                 arg = *argv++;
  147.                 /* Scan for an optional equal sign. */
  148.                 for (def = arg;    *def; def++) {
  149.                     if (*def == '=') {
  150.                         *def = '\0';
  151.                         def++;
  152.                         break;
  153.                     }
  154.                 }
  155.                 mst_enter(arg, def, -1);
  156.             }
  157.             else {
  158.                 printf("Trailing -d\n");
  159.                 exit(BAD_EXIT);
  160.             }
  161.         }
  162.         else if (str_eq(arg, "-i")) {
  163.             insert_flag = TRUE;
  164.         }
  165.         else if (str_eq(arg, "-f")) {
  166.             if (argc--) {
  167.                 arg = *argv++;
  168.                 if (sysopen(arg) == FALSE) {
  169.                     printf("Can not open %s\n", arg);
  170.                     sysabort();
  171.                 }
  172.                 hold_flag = TRUE;
  173.                 synonyms();
  174.                 sysiclose();
  175.                 syshkill();
  176.                 ch = ' ';
  177.                 hold_flag = FALSE;
  178.                 ch_hold   = FALSE;
  179.             }
  180.             else {
  181.                 printf("Trailing -f\n");
  182.                 exit(BAD_EXIT);
  183.             }
  184.         }
  185.         else if (str_eq(arg, "-n")) {
  186.             /* Allow nested comments. */
  187.             nest_flag = TRUE;
  188.         }
  189.         else if (str_eq(arg, "-o")) {
  190.             usr_flag    = TRUE;
  191.             printf_flag = FALSE;
  192.         }
  193.         else if (str_eq(arg, "-s")) {
  194.             /* Define a path. */
  195.             if (argc--) {
  196.                 arg = *argv++;
  197.                 if (n_paths >= MAX_PATHS) {
  198.                     printf("too many path names.\n");
  199.                     exit(BAD_EXIT);
  200.                 }
  201.                 else {
  202.                     p1 = str_mcat(arg, "\\");
  203.                     paths [n_paths++] = p1;
  204.                 }
  205.             }
  206.             else {
  207.                 printf("Trailing -s.\n");
  208.                 exit(BAD_EXIT);
  209.             }
  210.         }
  211.         else if (str_eq(arg, "-t")) {
  212.             tick_flag = TRUE;
  213.         }
  214.         else if(str_eq(arg, "-u")) {
  215.             /* Suppress the initial definition of a variable. */
  216.             if (argc--) {
  217.                 arg = *argv++;
  218.                 mst_unarg(arg);
  219.             }
  220.             else {
  221.                 printf("Trailing -u.\n");
  222.                 exit(BAD_EXIT);
  223.             }
  224.         }
  225.         else if (str_eq(arg, "-x")) {
  226.             slc_flag = FALSE;
  227.         }
  228.         else if (str_eq(arg, "-?")) {
  229.             /* Ignore it. */
  230.             ;
  231.         }
  232.         else if (in == NULL) {
  233.             in = arg;
  234.         }
  235.         else if (out == NULL) {
  236.             out = arg;
  237.         }
  238.         else {
  239.             printf("Extra file argument: %s\n", arg);
  240.             exit(BAD_EXIT);
  241.         }
  242.     }
  243.  
  244.     /* Make sure that both file arguments were provided. */
  245.     if (in == NULL) {
  246.         printf("Missing input, output file arguments.\n");
  247.         exit(BAD_EXIT);
  248.     }
  249.     else if (out == NULL) {
  250.         printf("Missing output file argument.\n");
  251.         exit(BAD_EXIT);
  252.     }
  253.     else if (str_eq(in, out)) {
  254.         fatal("Can not copy input file to output file");
  255.     }
  256.  
  257.     /*
  258.         Set search path from the INCLUDE environment variable.
  259.         Do this AFTER the -s paths have been entered.
  260.     */
  261.     arg = getenv("INCLUDE");
  262.     if (arg != 0) {
  263.         strcpy(path_buf, arg);
  264.         arg = path_buf;
  265.         for (p = &path_buf[0]; ;) {
  266.             if (*p != ';' && *p != '\0') {
  267.                 p++;
  268.                 continue;
  269.             }
  270.             if (*p == ';') {
  271.                 *p = '\0';
  272.                 p++;
  273.             }
  274.             if (n_paths >= MAX_PATHS) {
  275.                 printf("too many default path names.\n");
  276.                 exit(BAD_EXIT);
  277.             }
  278.             else {
  279.                 p1 = str_mcat(arg, "\\");
  280.                 TRACEP("main",
  281.                     printf("default path: %s\n", arg));
  282.                 paths [n_paths++] = p1;
  283.             }
  284.             if (*p == '\0') {
  285.                 break;
  286.             }
  287.             else {
  288.                 arg = p;
  289.             }
  290.         }
  291.     }
  292.  
  293.     /*
  294.         Open the output file.
  295.  
  296.         This should be done BEFORE opening the input file because
  297.         opening the input file will cause a character to be written
  298.         to the output file.
  299.     */
  300.     if (syscreat(out) == FALSE) {
  301.         printf("Can not open %s\n", out);
  302.         exit(BAD_EXIT);
  303.     }
  304.  
  305.     /* Open the input file. */
  306.     if (sysopen(in) == FALSE) {
  307.         printf("Can not open %s\n", in);
  308.         sysabort();
  309.     }
  310.  
  311.     /*
  312.         Initialize the predefined macros (__line__ and __file__) here
  313.         so that they can be suppressed with the -u command line option.
  314.     */
  315.     mst2_init();
  316.  
  317.     /* Insert sl.h if requested. */
  318.     if (insert_flag) {
  319.         syssput("#include \"sl.h\"");
  320.         sysnlput();
  321.     }
  322.  
  323.     /*
  324.         Start off at a new line.
  325.         This is somewhat kludgy, because we need a GENERAL way of
  326.         allowing preprocessor directives at the start of EVERY file.
  327.     */
  328.     begin_line(TRUE);
  329.  
  330.     /* Parse the program !! */
  331.     program();
  332.  
  333.     /* Close the output file. */
  334.     syshflush();
  335.     sysoclose();
  336.  
  337.     TRACE("m_stat", m_stat());
  338.     TRACE("dump", sl_dump());
  339.  
  340.     sysend();
  341. }
  342.  
  343. /*
  344.     Return the next token from the